module lpuart_pin_proc(
  input            uart_clk,
  input            uart_rst_n,

  input            hdsel,
  input            txinv,
  input            rxinv,
  input            swap_tx_rx,

  input            fifo_en,
  input            rxfnf,
  input            rxne,
  input            rts_en,

  input            tx_out_en,
  input            tx_out,
  output           rxd_sync,

  input            rx_pin_in,
  input            tx_pin_in,
  output           rx_pin_out,
  output           rx_pin_oe,
  output           tx_pin_out,
  output           tx_pin_oe,
  output reg       rts_oe,
  output           rts_n
);

// swap
wire rx_in  = swap_tx_rx ? tx_pin_in  : rx_pin_in;
wire rx_data = rxinv ? ~rx_in : rx_in;

assign tx_pin_oe = swap_tx_rx ? ~tx_out_en: tx_out_en;
assign rx_pin_oe = swap_tx_rx ? ~tx_out_en: 1'b0;

assign tx_out_tmp = txinv ? ~tx_out : tx_out;
assign rx_pin_out = swap_tx_rx ? tx_out_tmp : 1'b1;
assign tx_pin_out = swap_tx_rx ? 1'b1 : tx_out_tmp;

// sync rx & hdsel tx_pin_in
reg [1:0] tx_pin_in_sync;
reg [1:0] rx_data_sync;
always @(posedge uart_clk, negedge uart_rst_n)
  if (!uart_rst_n) 
    tx_pin_in_sync <= 2'b11;     
  else
    tx_pin_in_sync <= (tx_out_en) ? 2'b11 : {tx_pin_in_sync[0],tx_pin_in};

always @(posedge uart_clk, negedge uart_rst_n)
  if (!uart_rst_n) 
    rx_data_sync <= 2'b11;     
  else
    rx_data_sync <= {rx_data_sync[0],rx_data}; 

assign rxd_sync =  hdsel ? tx_pin_in_sync[1] : rx_data_sync[1];

assign rts_n  = fifo_en ? ~rxfnf : rxne;

always @(posedge uart_clk, negedge uart_rst_n)
  if (!uart_rst_n) 
    rts_oe <= 1'b1;     
  else
    rts_oe <= rts_en; 

endmodule
